package com.triones.yjj.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.imgconflate.Const;
import com.ruoyi.common.imgconflate.PosterQrcodeUtil;
import com.ruoyi.common.utils.*;
import com.ruoyi.system.service.ISysConfigService;
import com.triones.biz.infra.entity.file.FileConfigDO;
import com.triones.biz.infra.entity.file.vo.FileConfigVO;
import com.triones.biz.infra.entity.file.vo.FileVO;
import com.triones.biz.infra.mapper.file.FileConfigMapper;
import com.triones.biz.infra.service.file.FileService;
import com.triones.framework.common.util.StringUtil;
import com.triones.framework.file.core.client.local.LocalFileClientConfig;
import com.triones.yjj.entity.*;
import com.triones.yjj.entity.bo.PosterBO;
import com.triones.yjj.entity.vo.ActivityVO;
import com.triones.yjj.entity.vo.MemberDetailVO;
import com.triones.yjj.entity.vo.MiniCodeSceneVO;
import com.triones.yjj.entity.vo.OrderVO;
import com.triones.yjj.mapper.*;
import com.triones.yjj.service.QrService;
import com.triones.yjj.service.WeChatManager;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 二维码 service 业务实现
 *
 * @Author: triones
 */
@Service
@RequiredArgsConstructor
public class QrServiceImpl implements QrService {

    private final QrMapper qrMapper;

    private final FileConfigMapper fileConfigMapper;

    private final RuoYiConfig ruoYiConfig;

    private final WeChatManager weChatManager;

    private final MiniCodeSceneMapper miniCodeSceneMapper;

    private final FileService fileService;

    private final ActivityMapper activityMapper;

    private final MemberMapper memberMapper;

    private final OrderMapper orderMapper;

    private final ShareMapper shareMapper;

    private final ShareRecordMapper shareRecordMapper;
    @Autowired
    private ISysConfigService sysConfigService;

    @Override
    public String qrCreate(String qrValue) {
        String qrImg = "";
        LambdaQueryWrapper<QrDO> wrapper = Wrappers.lambdaQuery(QrDO.class);
        wrapper.eq(QrDO::getQrValue,qrValue);
        QrDO qrDO = qrMapper.selectOne(wrapper);
        if (qrDO != null) {
            qrImg = qrDO.getQrImg();
        } else {
            String basePath = sysConfigService.selectConfigByKey("sys.base.file.dir");
            if(StringUtils.isEmpty(basePath)){
                basePath = "/files";
            }
           /* QueryWrapper<FileConfigDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("master", 1);
            queryWrapper.eq("deleted", 0);
            queryWrapper.last(" LIMIT 1");
            FileConfigVO configVO = fileConfigMapper.selectVoOne(queryWrapper);
            LocalFileClientConfig clientConfig = (LocalFileClientConfig) configVO.getConfig();
            String basePath = clientConfig.getBasePath();*/
            String path = ruoYiConfig.getName() + "/" + SnCreator.getRandomSn() + "/" + "qrcode.png";
//            String domain = clientConfig.getDomain();
//            StringUtil.createQr(qrValue, basePath + path);
//            String prePath = domain+"/infra/file/"+configVO.getId()+"/get/";
            try {
                File file =  StringUtil.getCreateQrFile(qrValue, basePath + path);
                FileInputStream fis = new FileInputStream(file);
                FileVO fileVo = fileService.upload(file.getName(),null, IoUtil.readBytes(fis),null);
                fis.close();
                qrDO = new QrDO();
                qrDO.setQrValue(qrValue);
                qrDO.setQrImg(fileVo.getUrl());
                qrDO.setCreateTime(DateUtil.getDateTimeString());
                qrMapper.insert(qrDO);
                qrImg = fileVo.getUrl();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return qrImg;
    }

    @Override
    public String createPosterQr(String qrValue) {
        String qrImg = "";
        LambdaQueryWrapper<QrDO> wrapper = Wrappers.lambdaQuery(QrDO.class);
        wrapper.eq(QrDO::getQrValue,qrValue);
        QrDO qrDO = qrMapper.selectOne(wrapper);
        if (qrDO != null) {
            qrImg = qrDO.getQrImg();
        } else {
            QueryWrapper<FileConfigDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("master", 1);
            queryWrapper.eq("deleted", 0);
            queryWrapper.last(" LIMIT 1");
            FileConfigVO configVO = fileConfigMapper.selectVoOne(queryWrapper);
            LocalFileClientConfig clientConfig = (LocalFileClientConfig) configVO.getConfig();
            String basePath = clientConfig.getBasePath();
            String path = "/" + ruoYiConfig.getName() + "/" + SnCreator.getRandomSn() + "/" + "qrcode.png";
            String domain = clientConfig.getDomain();
            StringUtil.createPosterQr(qrValue, basePath + path);
            String prePath = domain+"/infra/file/"+configVO.getId()+"/get/";

            qrDO = new QrDO();
            qrDO.setQrValue(qrValue);
            qrDO.setQrImg(prePath + path);
            qrDO.setCreateTime(DateUtil.getDateTimeString());
            qrMapper.insert(qrDO);
            qrImg = prePath + path;
        }
        return qrImg;
    }

    @Override
    public R<Map> getMiniCodeImg(String page, String scene) {
        Map map = new HashMap();
        /**
         * 保存请求参数
         */
        MiniCodeSceneDO miniCodeSceneDO = new MiniCodeSceneDO();
        miniCodeSceneDO.setScene(scene);
        miniCodeSceneMapper.insert(miniCodeSceneDO);
//        String miniCodeImg = weChatManager.getMiniCodeImg(page, Convert.toStr(miniCodeSceneDO.getId()));
        String miniCodeImg = weChatManager.getMiniCodeImg(Convert.toStr(miniCodeSceneDO.getId()),null);
        map.put("miniCodeImgBase64",miniCodeImg);
        return R.ok(map);
    }

    @Override
    public R<Map> getMiniCodeScene(String uuid) {
        Map map = new HashMap();
        MiniCodeSceneVO miniCodeSceneVO = miniCodeSceneMapper.selectVoById(Convert.toLong(uuid));
        if (miniCodeSceneVO == null) {
            throw new ServiceException("记录不存在");
        }
        map.put("scene",miniCodeSceneVO.getScene());
        return R.ok(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map getMiniCodeImg(PosterBO bo) throws Exception {

        Map map = new HashMap();
        ActivityVO activityVO = activityMapper.selectVoById(bo.getActivityId());
        if (activityVO == null) {
            throw new ServiceException("活动不存在");
        }
        HashMap contentMap = JSONUtil.toBean(activityVO.getContent(), HashMap.class);
        if (contentMap == null) {
            throw new ServiceException("活动内容不存在");
        }
        if (ObjectUtil.isEmpty(Convert.toStr(contentMap.get("poster_config"),null))) {
            throw new ServiceException("活动还未配置海报");
        }
        MemberDetailVO detailVO = memberMapper.selectDetailById(bo.getMemberId());
        if (detailVO == null) {
            throw new ServiceException("用户信息不存在");
        }
        Map params = new HashMap();
        HashMap posterConfigMap = JSONUtil.toBean(Convert.toStr(contentMap.get("poster_config")), HashMap.class);
        params.put("qrcodeObj",Convert.toStr(posterConfigMap.get("qrBoxObj"),null));
        if (ObjectUtil.isNotEmpty(Convert.toStr(posterConfigMap.get("textBox"),null))) {
            params.put("textBox",Convert.toStr(posterConfigMap.get("textBoxObj"),null));
        }
        if (ObjectUtil.isNotEmpty(Convert.toStr(posterConfigMap.get("headBox"),null)) && ObjectUtil.isNotEmpty(detailVO.getAvatarUrl())) {
            params.put("headBox",Convert.toStr(posterConfigMap.get("headBoxObj"),null));
            params.put("headBoxValue",detailVO.getAvatarUrl());
        }
        if (ObjectUtil.isNotEmpty(Convert.toStr(posterConfigMap.get("nickBox"),null)) && ObjectUtil.isNotEmpty(detailVO.getNickname())) {
            params.put("nickBox",Convert.toStr(posterConfigMap.get("nickBoxObj"),null));
            params.put("nickBoxValue",detailVO.getNickname());
        }

        /**
         * 保存请求参数
         */
        if (bo.getPage() == null) {
            bo.setPage("pages/index/index");
        }
        LambdaQueryWrapper<MiniCodeSceneDO> wrapper = Wrappers.lambdaQuery(MiniCodeSceneDO.class);
        wrapper.eq(MiniCodeSceneDO::getScene,bo.getScene());
        wrapper.eq(MiniCodeSceneDO::getPage,bo.getPage());
        MiniCodeSceneDO miniCodeSceneDO = miniCodeSceneMapper.selectOne(wrapper);
        String qrCodePath = null;
        if (miniCodeSceneDO == null) {
            miniCodeSceneDO = new MiniCodeSceneDO();
            miniCodeSceneDO.setScene(bo.getScene());
            miniCodeSceneDO.setPage(bo.getPage());
            miniCodeSceneMapper.insert(miniCodeSceneDO);

            /**
             * 获取微信二维码,并上传到服务器
             */
            String miniCodeImg = weChatManager.getMiniCodeImg(Convert.toStr(miniCodeSceneDO.getId()),miniCodeSceneDO.getPage());
            MultipartFile multipartFile = MultipartFileUtils.base64ToMultipartFile(miniCodeImg,Convert.toStr(System.currentTimeMillis()));
            FileVO fileVo = fileService.upload(multipartFile.getOriginalFilename(),null, IoUtil.readBytes(multipartFile.getInputStream()),null);
            miniCodeSceneDO.setMiniQrCodeImg(fileVo.getUrl());
            miniCodeSceneMapper.updateById(miniCodeSceneDO);
            qrCodePath = fileVo.getUrl();
        } else {
            qrCodePath = miniCodeSceneDO.getMiniQrCodeImg();
        }

        /**
         * 生成海报
         */
        MultipartFile file = PosterQrcodeUtil.overlapImage(qrCodePath,Convert.toStr(posterConfigMap.get("bgImg")), params);
        FileVO posterFile = fileService.upload(file.getOriginalFilename(),null, IoUtil.readBytes(file.getInputStream()),null);
        map.put("imgUrl",posterFile.getUrl());
        return map;
    }

    @Override
    public Map getTemplatePosterImg(PosterBO bo) throws Exception {
        Map map = new HashMap();
        ActivityVO activityVO = activityMapper.selectVoById(bo.getActivityId());
        if (activityVO == null) {
            throw new ServiceException("活动不存在");
        }
        HashMap contentMap = JSONUtil.toBean(activityVO.getContent(), HashMap.class);
        if (contentMap == null) {
            throw new ServiceException("活动内容不存在");
        }
        if (ObjectUtil.isEmpty(Convert.toStr(contentMap.get("poster_config"),null))) {
            throw new ServiceException("活动还未配置海报");
        }

        Map params = new HashMap();
        HashMap posterConfigMap = JSONUtil.toBean(Convert.toStr(contentMap.get("poster_config")), HashMap.class);
        params.put("qrcodeObj",Convert.toStr(posterConfigMap.get("qrBoxObj"),null));
        if (ObjectUtil.isNotEmpty(Convert.toStr(posterConfigMap.get("textBox"),null))) {
            params.put("textBox",Convert.toStr(posterConfigMap.get("textBoxObj"),null));
        }
        if (ObjectUtil.isNotEmpty(Convert.toStr(posterConfigMap.get("headBox"),null))) {
            params.put("headBox",Convert.toStr(posterConfigMap.get("headBoxObj"),null));
            params.put("headBoxValue",Const.wxHeadImg);
        }
        if (ObjectUtil.isNotEmpty(Convert.toStr(posterConfigMap.get("nickBox"),null))) {
            params.put("nickBox",Convert.toStr(posterConfigMap.get("nickBoxObj"),null));
            params.put("nickBoxValue",Const.wxNickname);
        }

        /**
         * 保存请求参数
         */
        if (bo.getPage() == null) {
            bo.setPage("pages/index/index");
        }
        LambdaQueryWrapper<MiniCodeSceneDO> wrapper = Wrappers.lambdaQuery(MiniCodeSceneDO.class);
        wrapper.eq(MiniCodeSceneDO::getScene,bo.getScene());
        wrapper.eq(MiniCodeSceneDO::getPage,bo.getPage());
        MiniCodeSceneDO miniCodeSceneDO = miniCodeSceneMapper.selectOne(wrapper);
        String qrCodePath = null;
        if (miniCodeSceneDO == null) {
            miniCodeSceneDO = new MiniCodeSceneDO();
            miniCodeSceneDO.setScene(bo.getScene());
            miniCodeSceneDO.setPage(bo.getPage());
            miniCodeSceneMapper.insert(miniCodeSceneDO);

            /**
             * 获取微信二维码,并上传到服务器
             */
            String miniCodeImg = weChatManager.getMiniCodeImg(Convert.toStr(miniCodeSceneDO.getId()),miniCodeSceneDO.getPage());
            MultipartFile multipartFile = MultipartFileUtils.base64ToMultipartFile(miniCodeImg,Convert.toStr(System.currentTimeMillis()));
            FileVO fileVo = fileService.upload(multipartFile.getOriginalFilename(),null, IoUtil.readBytes(multipartFile.getInputStream()),null);
            miniCodeSceneDO.setMiniQrCodeImg(fileVo.getUrl());
            miniCodeSceneMapper.updateById(miniCodeSceneDO);
            qrCodePath = fileVo.getUrl();
        } else {
            qrCodePath = miniCodeSceneDO.getMiniQrCodeImg();
        }

        /**
         * 生成海报
         */
        MultipartFile file = PosterQrcodeUtil.overlapImage(qrCodePath,Convert.toStr(posterConfigMap.get("bgImg")), params);
        FileVO posterFile = fileService.upload(file.getOriginalFilename(),null, IoUtil.readBytes(file.getInputStream()),null);
        map.put("imgUrl",posterFile.getUrl());
        map.put("imgMiniCodeUrl",qrCodePath);
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map getMemberPosterImg(Long memberId, Long activityId) throws Exception {
        Map map = new HashMap();
        PosterBO bo = new PosterBO();
        bo.setMemberId(memberId);
        bo.setActivityId(activityId);

        MemberDetailVO detailVO = memberMapper.selectDetailById(bo.getMemberId());
        if (detailVO == null) {
            throw new ServiceException("用户信息不存在");
        }

        ActivityVO activityVO = activityMapper.selectVoById(bo.getActivityId());
        if (activityVO == null) {
            throw new ServiceException("活动不存在");
        }
        HashMap contentMap = JSONUtil.toBean(activityVO.getContent(), HashMap.class);
        if (contentMap == null) {
            throw new ServiceException("活动内容不存在");
        }
        if (ObjectUtil.isEmpty(Convert.toStr(contentMap.get("poster_config"),null))) {
            throw new ServiceException("活动还未配置海报");
        }

        LambdaQueryWrapper<OrderDO> orderWrapper = Wrappers.lambdaQuery(OrderDO.class);
        orderWrapper.eq(OrderDO::getMemberId,memberId).eq(OrderDO::getActivityId,activityId).in(OrderDO::getStatus,2,5);
        OrderVO orderVO = orderMapper.selectVoOne(orderWrapper);
        if (orderVO == null) {
            throw new ServiceException("客户不存在可推广信息");
        }

        LambdaQueryWrapper<ShareDO> shareWrapper = Wrappers.lambdaQuery(ShareDO.class);
        shareWrapper.eq(ShareDO::getProductId,activityId).eq(ShareDO::getMemberId,memberId);
        ShareDO shareDO = shareMapper.selectOne(shareWrapper);
        if (shareDO == null) {
            shareDO = new ShareDO();
            shareDO.setMemberId(memberId);
            shareDO.setMemberWxUserId(detailVO.getWxUserId());
            shareDO.setProductId(activityId);
            shareDO.setProductType(1);
            shareDO.setShareNumber(0);
            shareDO.setSpreadNumber(0);
            shareDO.setMemberBuyNumber(0);
            shareDO.setBuyNumber(0);
            shareDO.setPayTotal(BigDecimal.ZERO);
            shareDO.setEnrollStatus(2);//未报名
            shareDO.setUserId(detailVO.getUserId());
            shareMapper.insert(shareDO);
        }
        ShareRecordDO shareRecordDO = new ShareRecordDO();
        shareRecordDO.setShareStaffId(orderVO.getPerformanceStaffId());
        shareRecordDO.setStaffWxUserId(orderVO.getStaffWxUserId());
        shareRecordDO.setShareId(shareDO.getId());
        shareRecordDO.setPassiveMemberId(memberId);
        shareRecordDO.setPassiveMemberWxUserId(detailVO.getWxUserId());
        shareRecordDO.setPreviousShareRecordId(orderVO.getShareRecordId());
        shareRecordDO.setUserId(detailVO.getUserId());
        shareRecordMapper.insert(shareRecordDO);
        String query = "isShare=0&activityId=" + activityId + "&staffId=" + orderVO.getPerformanceStaffId() +
            "&shareId=" + shareDO.getId() + "&shareRecordId=" + shareRecordDO.getId() + "&sharedTeamId=" + orderVO.getGroupPurchaseId();
        bo.setScene(query);

        Map params = new HashMap();
        HashMap posterConfigMap = JSONUtil.toBean(Convert.toStr(contentMap.get("poster_config")), HashMap.class);
        params.put("qrcodeObj",Convert.toStr(posterConfigMap.get("qrBoxObj"),null));
        if (ObjectUtil.isNotEmpty(Convert.toStr(posterConfigMap.get("textBox"),null))) {
            params.put("textBox",Convert.toStr(posterConfigMap.get("textBoxObj"),null));
        }
        if (ObjectUtil.isNotEmpty(Convert.toStr(posterConfigMap.get("headBox"),null)) && ObjectUtil.isNotEmpty(detailVO.getAvatarUrl())) {
            params.put("headBox",Convert.toStr(posterConfigMap.get("headBoxObj"),null));
            params.put("headBoxValue",detailVO.getAvatarUrl());
        }
        if (ObjectUtil.isNotEmpty(Convert.toStr(posterConfigMap.get("nickBox"),null)) && ObjectUtil.isNotEmpty(detailVO.getNickname())) {
            params.put("nickBox",Convert.toStr(posterConfigMap.get("nickBoxObj"),null));
            params.put("nickBoxValue",detailVO.getNickname());
        }

        /**
         * 保存请求参数
         */
        if (bo.getPage() == null) {
            bo.setPage("pages/index/index");
        }
        LambdaQueryWrapper<MiniCodeSceneDO> wrapper = Wrappers.lambdaQuery(MiniCodeSceneDO.class);
        wrapper.eq(MiniCodeSceneDO::getScene,bo.getScene());
        wrapper.eq(MiniCodeSceneDO::getPage,bo.getPage());
        MiniCodeSceneDO miniCodeSceneDO = miniCodeSceneMapper.selectOne(wrapper);
        String qrCodePath = null;
        if (miniCodeSceneDO == null) {
            miniCodeSceneDO = new MiniCodeSceneDO();
            miniCodeSceneDO.setScene(bo.getScene());
            miniCodeSceneDO.setPage(bo.getPage());
            miniCodeSceneMapper.insert(miniCodeSceneDO);

            /**
             * 获取微信二维码,并上传到服务器
             */
            String miniCodeImg = weChatManager.getMiniCodeImg(Convert.toStr(miniCodeSceneDO.getId()),miniCodeSceneDO.getPage());
            MultipartFile multipartFile = MultipartFileUtils.base64ToMultipartFile(miniCodeImg,Convert.toStr(System.currentTimeMillis()));
            FileVO fileVo = fileService.upload(multipartFile.getOriginalFilename(),null, IoUtil.readBytes(multipartFile.getInputStream()),null);
            miniCodeSceneDO.setMiniQrCodeImg(fileVo.getUrl());
            miniCodeSceneMapper.updateById(miniCodeSceneDO);
            qrCodePath = fileVo.getUrl();
        } else {
            qrCodePath = miniCodeSceneDO.getMiniQrCodeImg();
        }

        /**
         * 生成海报
         */
        MultipartFile file = PosterQrcodeUtil.overlapImage(qrCodePath,Convert.toStr(posterConfigMap.get("bgImg")), params);
        FileVO posterFile = fileService.upload(file.getOriginalFilename(),null, IoUtil.readBytes(file.getInputStream()),null);
        map.put("imgUrl",posterFile.getUrl());
        return map;
    }
}
